<?php
/**
 * Created by PhpStorm.
 * User: zhangchao
 * Date: 15/7/7
 * Time: 10:31
 */

namespace common\core;


use yii\helpers\Json;
use yii\web\Cookie;
use yii\web\IdentityInterface;
use yii\web\User;

class ZWebUser extends User {

    public $enableSession = true;

    private $_identity = false;

    private $_access = [];


    public function init()
    {
        parent::init();
    }

    /**
     * Returns the identity object associated with the currently logged-in user.
     * When [[enableSession]] is true, this method may attempt to read the user's authentication data
     * stored in session and reconstruct the corresponding identity object, if it has not done so before.
     * @param boolean $autoRenew whether to automatically renew authentication status if it has not been done so before.
     * This is only useful when [[enableSession]] is true.
     * @return IdentityInterface|null the identity object associated with the currently logged-in user.
     * `null` is returned if the user is not logged in (not authenticated).
     * @see login()
     * @see logout()
     */
    public function getIdentity($autoRenew = true)
    {
        if ($this->_identity === false) {
            if ($this->enableSession && $autoRenew) {
                $this->_identity = null;
                $this->renewAuthStatus();
            } else {
                return null;
            }
        }

        return $this->_identity;
    }

    /**
     * Sets the user identity object.
     *
     * Note that this method does not deal with session or cookie. You should usually use [[switchIdentity()]]
     * to change the identity of the current user.
     *
     * @param IdentityInterface|null $identity the identity object associated with the currently logged user.
     * If null, it means the current user will be a guest without any associated identity.
     * @throws InvalidValueException if `$identity` object does not implement [[IdentityInterface]].
     */
    public function setIdentity($identity)
    {
        if ($identity instanceof IdentityInterface) {
            $this->_identity = $identity;
            $this->_access = [];
        } elseif ($identity === null) {
            $this->_identity = null;
        } else {
            throw new InvalidValueException('The identity object must implement IdentityInterface.');
        }
    }


    public function login(IdentityInterface $identity, $duration = 0)
    {
        if(parent::beforeLogin($identity,false,$duration)){
            $this->switchIdentity($identity,$duration);
            $id = $identity->getId();
            $ip = \Yii::$app->getRequest()->getUserIP();
            if ($this->enableSession) {
                $log = "User '$id' logged in from $ip with duration $duration.";
            } else {
                $log = "User '$id' logged in from $ip. Session not enabled.";
            }
            \Yii::info($log, __METHOD__);


            $this->afterLogin($identity, false, $duration);
        }
        return !$this->getIsGuest();
    }

    function switchIdentity($identity, $duration = 0)
    {
        $this->setIdentity($identity);

        if (!$this->enableSession) {
            return;
        }

        $session = \Yii::$app->getSession();

        if (!YII_ENV_TEST) {
            $session->regenerateID(true);
        }

        $session->remove($session->getId());


        if ($identity) {
            $session->set(\Yii::$app->session->getId(),Json::encode($identity->toArray()));

            if ($duration > 0 && $this->enableAutoLogin) {
                $this->sendIdentityCookie($identity, $duration);
            }
        } elseif ($this->enableAutoLogin) {
            \Yii::$app->getResponse()->getCookies()->remove(new Cookie($this->identityCookie));
        }

    }

    protected function sendIdentityCookie($identity, $duration)
    {
        $cookie = new Cookie($this->identityCookie);
        $cookie->value = json_encode([
            $identity->getId(),
            $identity->getAuthKey(),
            $duration,
//            \Yii::$app->request->userAgent,
//            \Yii::$app->request->getUserIP(),
        ], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $cookie->expire = time() + $duration;
        \Yii::$app->getResponse()->getCookies()->add($cookie);
    }


    public function getIsGuest()
    {
        return $this->getIdentity() === null;
    }

}